package com.zgis.module.bas.util;

import org.geotools.geojson.GeoJSONUtil;
import org.geotools.geojson.geom.GeometryJSON;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;

import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.io.WKTReader;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;

import java.util.*;
import java.util.stream.Collectors;

import org.geotools.factory.Hints;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.GeometryFactory;

/**
 * 修改记录:
 * 24-09-29     zhengchaojun             首次创建
 */

/**
 * 类描述：该类提供了一系列静态方法，用于在WKT（Well-Known Text）和GeoJSON格式之间进行转换。
 */
public class CxWKT
{
    public static void main(String[] args)
    {
        try
        {
            List<Map<String, String>> list = new ArrayList<>();

            Map<String, String> map = new HashMap<>();
            map.put("geom", "POLYGON((88.429703 47.741777,88.439703 47.751777,88.459703 47.761777,88.429703 47.741777))");
            list.add(map);
            list.stream().map(entity ->
            {
                try
                {
                    System.out.println(CxWKT.wktToJson(entity.get("geom")));
                    entity.put("geom", CxWKT.wktToJson(entity.get("geom")));
                } catch (Exception e)
                {
                    throw new RuntimeException(e);
                }
                System.out.println(entity);
                return entity;
            }).collect(Collectors.toList());

//            System.out.println("WKT to GeoJSON: " + wktToJson("POLYGON((88.429703 47.741777,88.439703 47.751777,88.459703 47.761777,88.429703 47.741777))"));
//            System.out.println("WKT to GeoJSON: " + wktToJsonNode("POLYGON((88.429703 47.741777,88.439703 47.751777,88.459703 47.761777,88.429703 47.741777))"));
            System.out.println("GeoJSON to WKT: " + jsonToWkt(wktToJsonNode("POLYGON((88.429703 47.741777,88.439703 47.751777,88.459703 47.761777,88.429703 47.741777))")));
        } catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    /**
     * 将WKT字符串转换为GeoJSON字符串。
     *
     * @param wkt WKT格式的字符串。        POLYGON((88.429703 47.741777,88.439703 47.751777,88.459703 47.761777,88.429703 47.741777))
     * @return GeoJSON格式的字符串。       {"type":"Polygon","coordinates":[[[88.429703,47.741777],[88.439703,47.751777],[88.459703,47.761777],[88.429703,47.741777]]]}
     * @throws Exception 如果转换过程中发生错误。
     */
    public static String wktToJson(String wkt) throws Exception
    {
        WKTReader    reader   = new WKTReader();
        Geometry     geometry = reader.read(wkt);
        StringWriter writer   = new StringWriter();
        GeometryJSON g        = new GeometryJSON(8);
        g.write(geometry, writer);
        String json = writer.toString();
        return json;
    }

    /**
     * 将GeoJSON字符串转换为WKT字符串。
     *
     * @param geoJson GeoJSON格式的字符串。  {"type":"Point","coordinates":[10,20]}
     * @return WKT格式的字符串。             POINT (10 20)
     * @throws Exception 如果转换过程中发生错误。
     */
    public static String jsonToWkt(String geoJson) throws Exception
    {
        GeometryJSON gjson    = new GeometryJSON();
        Reader       reader   = new StringReader(geoJson);
        Geometry     geometry = gjson.read(reader);
        String       wkt      = geometry.toText();
        return wkt;
    }

    /**
     * 将GeoJSON字符串转换为Geometry对象。
     *
     * @param geoJson GeoJSON格式的字符串。
     * @return Geometry对象。
     * @throws Exception 如果转换过程中发生错误。
     */
    public static Geometry jsonToGeom(String geoJson) throws Exception
    {
        GeometryJSON gjson    = new GeometryJSON();
        Reader       reader   = new StringReader(geoJson);
        Geometry     geometry = gjson.read(reader);
        return geometry;
    }

    /**
     * 将WKT（Well-Known Text）字符串转换为JsonNode对象。
     * WKT是一种文本标记语言，用于表示矢量几何对象。
     *
     * @param wkt WKT格式的字符串。        POLYGON((88.429703 47.741777,88.439703 47.751777,88.459703 47.761777,88.429703 47.741777))
     * @return 转换后的JsonNode对象，如果转换失败则返回空对象。 {"type":"Polygon","coordinates":[[[88.429703,47.741777],[88.439703,47.751777],[88.459703,47.761777],[88.429703,47.741777]]]}
     */
    public static JsonNode wktToJsonNode(String wkt)
    {
        GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory((Hints) null);
        WKTReader       reader          = new WKTReader(geometryFactory);
        JsonNode        jsonObject      = (new ObjectMapper()).createObjectNode();

        try
        {
            Geometry     geometry     = reader.read(wkt);
            StringWriter writer       = new StringWriter();
            GeometryJSON geometryJSON = new GeometryJSON();
            geometryJSON.write(geometry, writer);
            jsonObject = (new ObjectMapper()).readTree(writer.toString());
        } catch (Exception var7)
        {
            Exception e = var7;
            System.out.println("WKT转GeoJson出现异常");
            e.printStackTrace();
        }

        return jsonObject;
    }

    /**
     * 将JsonNode对象转换为WKT格式的字符串。
     * JsonNode通常代表GeoJSON格式的数据。
     *
     * @param jsonObject GeoJSON格式的JsonNode对象。{"type":"Polygon","coordinates":[[[88.429703,47.741777],[88.439703,47.751777],[88.459703,47.761777],[88.429703,47.741777]]]}
     * @return 转换后的WKT格式字符串，如果转换失败则返回null。 POLYGON ((88.4297 47.7418, 88.4397 47.7518, 88.4597 47.7618, 88.4297 47.7418))
     */
    public static String jsonToWkt(JsonNode jsonObject)
    {
        String       wkt   = null;
        String       type  = jsonObject.path("type").asText();
        GeometryJSON gJson = new GeometryJSON();

        try
        {
            if ("GeometryCollection".equals(type))
            {
                ArrayNode  geometriesArray = (ArrayNode) jsonObject.get("geometries");
                int        size            = geometriesArray.size();
                Geometry[] geometries      = new Geometry[size];

                for (int i = 0; i < size; ++i)
                {
                    String   str      = geometriesArray.get(i).toString();
                    Reader   reader   = GeoJSONUtil.toReader(str);
                    Geometry geometry = gJson.read(reader);
                    geometries[i] = geometry;
                }

                GeometryCollection geometryCollection = new GeometryCollection(geometries, new GeometryFactory());
                wkt = geometryCollection.toText();
            }
            else
            {
                Reader   reader = GeoJSONUtil.toReader(jsonObject.toString());
                Geometry read   = gJson.read(reader);
                wkt = read.toText();
            }
        } catch (IOException var11)
        {
            IOException e = var11;
            System.out.println("GeoJson转WKT出现异常");
            e.printStackTrace();
        }

        return wkt;
    }
}
